package com.jmxcfc.blfsc.ninefour.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jmxcfc.blfsc.common.exception.NotifyException;
import com.jmxcfc.blfsc.ninefour.common.Constants;
import com.jmxcfc.blfsc.ninefour.entity.SendDetailSub;
import com.jmxcfc.blfsc.ninefour.entity.VoiceNotifyRecord;
import com.jmxcfc.blfsc.ninefour.entity.vo.NotifyResponseVo;
import com.jmxcfc.blfsc.ninefour.mapper.VoiceNotifyRecordMapper;
import com.jmxcfc.blfsc.ninefour.service.ISendDetailSubService;
import com.jmxcfc.blfsc.ninefour.service.IVoiceNotifyRecordService;
import com.jmxcfc.blfsc.ninefour.thread.SyncSendNotifyResultOperator;
import com.jmxcfc.blfsc.ninefour.util.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 94语音回调记录表 服务实现类
 * </p>
 *
 * @author pbs
 * @since 2024-06-24
 */
@Service
@Slf4j
public class VoiceNotifyRecordServiceImpl extends ServiceImpl<VoiceNotifyRecordMapper, VoiceNotifyRecord> implements IVoiceNotifyRecordService {


    /**
     * #客户服务key
     */
    @Value("${ninefour.appKey}")
    private String nfAppKey;

    /**
     * 秘钥由运营提供(企业信息中的appSecret)
     */
    @Value("${ninefour.appSecret}")
    private String nfAppSecret;

    private ISendDetailSubService sendDetailSubService;

    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    public void setSendDetailSubService(ISendDetailSubService sendDetailSubService) {
        this.sendDetailSubService = sendDetailSubService;
    }

    @Autowired
    public void setThreadPoolTaskExecutor(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
        this.threadPoolTaskExecutor = threadPoolTaskExecutor;
    }

    /**
     * ai挂断回调(外呼回调)
     * 1、解密:
     从header里取 timestamp,然后企业自己的secret
     解密:AESUtil.cbcDecrypt
     *
     * 2、处理流程:
     *(1)解密数据
     *(2)根据tag查询NF_SEND_DETAIL_SUB是否存在发送记录
     *(3)通知记录落库
     *(4)同步响应94语音接收通知结果,
     回调返回成功的标准是http状态码为200，并且返回的内容体的status参数也为200:
     {
     "status": 200,
     "message": "成功"
     }
     *
     * 异步调用blfs-sms模块的发送状态通知接口:
     1)通知状态的判断:
     根据94语音的通知参数 statusCode(外呼状态编码):
     (1:已接听、2:关机、3:空号、4:改号、5:停机、6:占线、7:拒接、8:无法接通、9:未接、10:用户欠费、11:线路故障、12:呼叫失败、30:已拦截、40:单日呼叫次数受限)
     备注: 为1则说明成功
     2)请求参数组织
     *  @param sign 头部参数:签名
     * @param appKey 头部参数:客户服务key
     * @param timestamp 头部参数:时间戳
     * @param encryptNotifyData 通知数据:加密(需要解密)
     * @return
     */
    @Override
    public NotifyResponseVo voiceNotifyHandler(String sign,String appKey,String timestamp,String encryptNotifyData) {
        try {
            if (StringUtils.isAnyBlank(sign,appKey,timestamp,encryptNotifyData)|| !StringUtils.equals(appKey,nfAppKey)){
                log.error("94语音-【ai挂断回调(外呼回调)】,回调通知请求参数存在空值或者错误,结束处理,数据接收失败,头部参数sign:{},头部参数appKey:{},头部参数timestamp:{},通知数据data:{}", sign, appKey, timestamp, encryptNotifyData);
                return NotifyResponseVo.fail("通知参数存在为空或者错误");
            }else{
                JSONObject content = Optional.ofNullable(JSON.parseObject(AESUtil.cbcDecrypt(encryptNotifyData, nfAppSecret, AESUtil.genTimestampIV(timestamp))))
                        .orElseThrow(() -> {
                            log.error("94语音-【ai挂断回调(外呼回调)】,加密的通知数据data:{},解密异常,解密结果结果为空", encryptNotifyData);
                            return new NotifyException();
                        });
                log.info("94语音-【ai挂断回调(外呼回调)】,加密的通知数据data:{},解密后的数据:{}",encryptNotifyData,content);
                String tag = content.getString(Constants.TAG);
                SendDetailSub sendDetailSub = sendDetailSubService.getById(tag);
                if (Objects.isNull(sendDetailSub)) {
                    log.error("94语音-【ai挂断回调(外呼回调)】,根据通知参数tag【标识一条语音的流水号uuid】:{} 94语音厂商发送明细表未查询到发送记录数据",tag);
                    return NotifyResponseVo.fail("我方未查询到发送记录数据");
                }
                VoiceNotifyRecord voiceNotifyRecord = new VoiceNotifyRecord();
                //对方传了id字段,所以这边忽略该字段
                BeanUtil.copyProperties(content, voiceNotifyRecord,"id");

                voiceNotifyRecord.setCellPhoneNo(content.getString(Constants.NUMBER));
                voiceNotifyRecord.setRequestNo(sendDetailSub.getRequestNo());
                voiceNotifyRecord.setRequestId(sendDetailSub.getRequestId());
                this.save(voiceNotifyRecord);
                log.info("94语音-【ai挂断回调(外呼回调)】,tag【标识一条语音的流水号uuid】:{},通知数据落库成功",tag);
                //异步发起调用blfs-sms 进行发送状态(语音发送状态) 通知
                threadPoolTaskExecutor.execute(new SyncSendNotifyResultOperator(tag,sendDetailSub, null, voiceNotifyRecord));
            }
        } catch (Exception e) {
            log.error("94语音-【ai挂断回调(外呼回调)】处理异常,异常信息:{}", e.getMessage(), e);
            throw new NotifyException();
        }
        return NotifyResponseVo.success();
    }
}
